﻿using System;
using System.Threading.Tasks;
using Windows.Networking.Connectivity;
using com.IronOne.BoardPACWinAppBO.General;
using com.IronOne.BoardPACWinAppService.Init;
using com.IronOne.BoardPACWinAppUtil.Util;
using GalaSoft.MvvmLight.Messaging;

namespace com.IronOne.BoardPACWinApp.Helpers
{
    public class NetworkConnectivityManager
    {
        //public static bool IsOnline = false;
        /// <summary>
        ///     True if user went offline intentionally
        /// </summary>
        //public static bool UserForceWentOffline = false;
        public static bool IsInternetAccess;

        public static bool IsLocalAccess;
        public static bool IsWifi;
        public static bool Is3GMobile;

        /// <summary>
        ///     Use miliseconds for the value
        /// </summary>
        private const int ServerUpChecktime = 30000; // 60 Sec is the default

        /// <summary>
        ///     Use miliseconds for the value
        /// </summary>
        private const int NoInternetWaitCheck = 10000; // 10 Sec

        //private void HandleMessages(NotificationMessage<MessageDataModel> mdm)
        //{
        //}

        private static void DeviceConnectivityCheck()
        {
            var connections = NetworkInformation.GetInternetConnectionProfile();
            IsInternetAccess = connections != null &&
                               connections.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess;
            IsLocalAccess = connections != null &&
                            connections.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.LocalAccess;

            var profile = NetworkInformation.GetInternetConnectionProfile();
            if (profile == null) return;

            var interfaceType = profile.NetworkAdapter.IanaInterfaceType;

            // NOTE: WiFi == 71 | Ethernet(LAN) == 6
            IsWifi = (interfaceType == 71);

            // Note: 3G/Mobile == 243 & 244
            Is3GMobile = (interfaceType == 243 || interfaceType == 244);
        }

        public static async void ServerUpCheck()
        {
            while (true)
            {
                try
                {
                    DeviceConnectivityCheck();

                    if (!IsInternetAccess && !IsLocalAccess)
                    {
                        var mdm = new MessageDataModel {MessageData = false};
                        var message = new NotificationMessage<MessageDataModel>(mdm, MessageCodes.IS_ONLINE);
                        Messenger.Default.Send(message);

                        await Task.Delay(NoInternetWaitCheck);
                        continue;
                    }

                    IInitService initService = new InitService();
                    Global.IsOnline = await initService.ServerUpCheck();

                    if (Global.IsOnline)
                    {
                        var mdm = new MessageDataModel {MessageData = true};
                        var message = new NotificationMessage<MessageDataModel>(mdm, MessageCodes.IS_ONLINE);
                        Messenger.Default.Send(message);
                    }
                    else
                    {
                        var mdm = new MessageDataModel {MessageData = false};
                        var message = new NotificationMessage<MessageDataModel>(mdm, MessageCodes.IS_ONLINE);
                        Messenger.Default.Send(message);
                    }

                    await Task.Delay(ServerUpChecktime);
                }
                catch (Exception)
                {
                    Global.IsOnline = false;

                    var mdm = new MessageDataModel {MessageData = false};
                    var message = new NotificationMessage<MessageDataModel>(mdm, MessageCodes.IS_ONLINE);
                    Messenger.Default.Send(message);
                }
            }
        }

        public static async Task<bool> ServerUpCheckOnce()
        {
            try
            {
                DeviceConnectivityCheck();

                if (!IsInternetAccess && !IsLocalAccess)
                {
                    Global.IsOnline = false;
                    return false;
                }

                IInitService initService = new InitService();
                Global.IsOnline = await initService.ServerUpCheck();

                return Global.IsOnline;
            }
            catch (Exception)
            {
                Global.IsOnline = false;
                return false;
            }
        }
    }
}